package com.apps.globals.color.utils;

import cn.hutool.core.img.BackgroundRemoval;
import com.apps.globals.color.model.vo.HSV;
import com.apps.globals.color.model.vo.RGB;
import com.sun.javafx.util.Utils;
import lombok.SneakyThrows;
import net.coobird.thumbnailator.Thumbnails;

import javax.imageio.ImageIO;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;

/**
 * 识别图片的主色调
 */
public class ColorCountUtils {

    // 十进制转十六进制
    @SuppressWarnings({ "static-access", "deprecation" })
    public String tenToHex(int x) {
        Integer ten = new Integer(x);
        String hex = ten.toHexString(ten);

        return hex;
    }

    // 十六进制转十进制
    public Integer hexToTen(String hex) {
        Integer x = Integer.parseInt(hex, 16);
        return x;
    }

//    //将BufferImage取出来的rgb int 值转换为三位数的rgb
//    public static  RGB changeToRgb(int pixel)
//    {
//        RGB rgb=new RGB();
//        rgb.setR((pixel & 0xff0000) >> 16);
//        rgb.setG((pixel & 0xff00) >> 8);
//        rgb.setB((pixel & 0xff));
//        return rgb;
//    }

    /**
     * 识别出图片主要颜色
     * @param path
     * @param rgbreject 需要排除的颜色
     * @return
     */
    public static  List<RGB> recognition(String path,RGB... rgbreject)
    {
        try {
            BufferedImage bi = ImageIO.read(new File(path));
            return recognition(bi,rgbreject);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 识别出图片主要颜色
     * @param bufferedImage
     * @param rgbreject  需要排除的颜色
     * @return
     */
    @SuppressWarnings("deprecation")
    public static  List<RGB> recognition(BufferedImage bufferedImage,RGB... rgbreject)
    {
        try {
            BufferedImage bi = Thumbnails.of(bufferedImage).size(100, 100).asBufferedImage();
            Map<Integer, Integer> colorCount = new HashMap<>();
            // 统计图中颜色标准的数量分布情况
            for (int w = 0; w < bi.getWidth(); w = w + 2) {
                for (int h = 0; h < bi.getHeight(); h = h + 2) {
                    // 统计下每一个颜色对应的像素数量
                    int rgb=bi.getRGB(w, h);
                    // 统计下每一个颜色对应的像素数量
                    Integer count = colorCount.get(rgb);
                    if (count == null) {
                        count = new Integer(0);
                    }
                    count++;
                    colorCount.put(rgb, count);
                }
            }
            Map<Integer, Integer> colorCountRev = new HashMap<>();
            List<Integer> countList = new ArrayList<Integer>();
            for (Integer key : colorCount.keySet()) {
                colorCountRev.put(colorCount.get(key), key);
                countList.add(colorCount.get(key));
            }
            // 排序
            Collections.sort(countList);
            int length = countList.size();
            if (length > 6) {
                length = 2;
            }

            // 取出数量最多的前五种颜色
            List<RGB> colors = new ArrayList<>();
            for (int i = 1; i <= length; i++)
            {
                RGB rgb=new RGB(colorCountRev.get(countList.get(countList.size() - i)));
                int count=0;
                for(RGB item:rgbreject)
                {
                    if(distance(new HSV(rgb),new HSV(item)) <=5)
                        count++;
                }
                if(count<=0)
                   colors.add(rgb);
            }
            return colors;

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 求出颜色距离,一般小于10说明是同一种颜色
     * @param hsv1
     * @param hsv2
     * @return
     */
    public static double distance(HSV hsv1, HSV hsv2)
    {
        //self-defined
        double R = 100;
        double angle = 30;
        double h = R * Math.cos(angle / 180 * Math.PI);
        double r = R * Math.sin(angle / 180 * Math.PI);

        double x1 = r * hsv1.getV() * hsv1.getS() * Math.cos(hsv1.getH() / 180 * Math.PI);
        double y1 = r * hsv1.getV() * hsv1.getS() * Math.sin(hsv1.getH() / 180 * Math.PI);
        double z1 = h * (1 - hsv1.getV());
        double x2 = r * hsv2.getV() * hsv2.getS() * Math.cos(hsv2.getH() / 180 * Math.PI);
        double y2 = r * hsv2.getV() * hsv2.getS() * Math.sin(hsv2.getH() / 180 * Math.PI);
        double z2 = h * (1 - hsv2.getV());
        double dx = x1 - x2;
        double dy = y1 - y2;
        double dz = z1 - z2;
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    }


    @SneakyThrows
    public static void main(String... args)
    {
         System.out.println(distance(new HSV(187,224,245),new HSV(255,255,255)));

    }
}
